import { Ionicons } from '@expo/vector-icons'; import { useLocalSearchParams, useRouter } from 'expo-router'; import { ActivityIndicator, Pressable, ScrollView, StyleSheet, Switch, Text, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { usePrivacyDetailSetting } from '../../../src/hooks'; import { colors } from '../../../src/theme'; import type { PrivacyDetailOption } from '../../../src/types'; /* ===================== 子组件:顶部导航 ===================== */ function Header({ title, onBack }: { title: string; onBack: () => void }) { return ( {title} ); } /* ===================== 子组件:可选项行 ===================== */ function OptionRow({ item, disabled, isLast, onToggle, }: { item: PrivacyDetailOption; disabled: boolean; isLast: boolean; onToggle: (id: string, enabled: boolean) => void; }) { return ( {item.title} {item.description ? {item.description} : null} onToggle(item.id, next)} trackColor={{ false: colors.border, true: colors.primaryBorder }} thumbColor={item.enabled ? colors.primary : colors.white} /> ); } /* ===================== 页面 ===================== */ export default function PrivacyDetailScreen() { const params = useLocalSearchParams(); const rawId = params.id; const id = typeof rawId === 'string' ? rawId : Array.isArray(rawId) ? rawId[0] ?? '' : ''; const router = useRouter(); const { detail, loading, error, refresh, toggle } = usePrivacyDetailSetting(id); if (loading) { return (
router.back()} /> ); } if (error || !detail) { return (
router.back()} /> {detail === null ? '暂无该设置项' : '加载失败,请重试'} 重试 ); } return (
router.back()} /> {detail.intro} 主开关 {detail.master.title} toggle(detail.master.id, next)} trackColor={{ false: colors.border, true: colors.primaryBorder }} thumbColor={detail.master.enabled ? colors.primary : colors.white} /> 细选项 {detail.options.map((item, index) => ( ))} {detail.note ? ( {detail.note} ) : null} ); } const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: colors.pageBg, }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 8, height: 48, backgroundColor: colors.white, borderBottomWidth: 1, borderBottomColor: colors.borderLight, }, headerBtn: { width: 40, height: 40, alignItems: 'center', justifyContent: 'center', }, headerTitle: { flex: 1, textAlign: 'center', fontSize: 17, fontWeight: '700', color: colors.textPrimary, }, scroll: { flex: 1, }, content: { padding: 8, paddingBottom: 24, }, stateBox: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12, }, stateText: { marginTop: 12, fontSize: 14, color: colors.textSecondary, }, retryBtn: { marginTop: 16, paddingHorizontal: 24, paddingVertical: 8, borderRadius: 18, backgroundColor: colors.primaryBtn, }, retryText: { fontSize: 13, fontWeight: '600', color: colors.white, }, introCard: { backgroundColor: colors.infoLight, borderRadius: 8, padding: 8, marginBottom: 8, }, introText: { fontSize: 13, lineHeight: 19, color: colors.textSecondary, }, section: { marginBottom: 16, }, sectionTitle: { fontSize: 14, fontWeight: '700', color: colors.textPrimary, marginBottom: 10, }, card: { backgroundColor: colors.white, borderRadius: 8, overflow: 'hidden', }, row: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: 14, paddingVertical: 14, }, rowBorder: { borderBottomWidth: 1, borderBottomColor: colors.borderLight, }, rowBody: { flex: 1, marginRight: 12, }, rowTitle: { fontSize: 15, fontWeight: '600', color: colors.textPrimary, }, rowTitleDisabled: { color: colors.textHint, }, rowDesc: { marginTop: 3, fontSize: 12, lineHeight: 16, color: colors.textSecondary, }, noteCard: { flexDirection: 'row', alignItems: 'flex-start', backgroundColor: colors.white, borderRadius: 8, padding: 8, gap: 8, }, noteText: { flex: 1, fontSize: 12, lineHeight: 18, color: colors.textSecondary, }, });